package com.zshan.clinic.admin.util;

import com.zshan.clinic.common.constant.CommonConstant;
import com.zshan.clinic.common.enums.YesOrNoEnum;
import com.zshan.clinic.common.util.decimal.BigDecimalUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;


/**
 * 处方工具类
 * @author lichen
 */
public class RxUtil {

    /**
     * 验证库存
     * @param minPackQty 最小包装数一盒有几片
     * @param stockQty 整盒的库存 10盒
     * @param minStockQty 散装的库存 2片
     * @param totalOutQty 出库量 12片
     * @param isSplit 是否允许拆分，如果不允许代表只能整合卖
     * @return
     */
    public boolean validateStorage(Integer minPackQty, Integer stockQty,Integer minStockQty,Integer totalOutQty,String isSplit) {
        if (YesOrNoEnum.NO.getValue().equals(isSplit)) {
            //如果不允许拆分，那么totalOutQty代表的就是几盒，需要拆分成多少片
            totalOutQty = totalOutQty * minPackQty;
        }
        // 计算总库存（全部换算成片数）
        int totalStockQty = (stockQty * minPackQty) + minStockQty;
        // 判断库存是否足够
        return totalStockQty >= totalOutQty;
    }

    /**
     * 计算用药总量（单位：最小单位，比如片数）
     * @param dosage 每次用量（可小数，如0.33片）
     * @param frequencyTimes 每天用药次数
     * @param cycle 用药周期
     * @param isMinSplit 是否允许最小单位拆分（true允许，false向上取整整片）
     *                   当不允许拆分时，每次用量向上取整成整片后累加
     * @param isSplit 是否允许拆分，如果不允许代表只能整合卖
     * @param minPackQty 每盒最小单位数量（片数）
     * @return 总用药量，BigDecimal类型，可能含小数
     */
    public static Integer calculateTotalDose(BigDecimal dosage, int frequencyTimes, int cycle,String isMinSplit,String isSplit, int minPackQty) {
        //总的出库量
        BigDecimal totalDose = BigDecimal.ZERO;
        for (int day = 0; day < cycle; day++) {
            //先循环周期 3天
            for (int time = 0; time < frequencyTimes; time++) {
                //在循环次数  1天3次
                BigDecimal actualDose = dosage;
                if (YesOrNoEnum.NO.getValue().equals(isMinSplit)) {
                    //向上取整
                    actualDose = BigDecimalUtils.format(actualDose, RoundingMode.UP,CommonConstant.DEFAULT_0);
                }
                //累加单次的用量
                totalDose = totalDose.add(actualDose);
            }
        }
        //出库数量（片）向上取整
        int leftoverPieces = BigDecimalUtils.format(totalDose,RoundingMode.UP,CommonConstant.DEFAULT_0).intValue();
        if(YesOrNoEnum.YES.getValue().equals(isSplit)){
            return leftoverPieces;
        }
        //如果不允许拆零销售代表只能按整盒出库，用总的片数除以每盒有多少片，然后在向上取整
        int fullBoxes = BigDecimalUtils.divide(BigDecimal.valueOf(leftoverPieces), BigDecimal.valueOf(minPackQty), RoundingMode.UP, CommonConstant.DEFAULT_0).intValue();
        return fullBoxes;
    }

    /**
     * 根据总用量计算出库数量和价格
     * @param totalOutQty 总用药量（片数），可含小数
     * @param minPackQty 每盒最小单位数量（片数）
     * @param isSplit 是否允许拆零销售（true允许，false必须整盒）
     * @param price 药品的整盒的价格
     * @param splitPrice 药品的单片价格
     */
    public static Integer calculatePrice(int totalOutQty,
                                         int minPackQty,
                                         String isSplit,
                                         int price,
                                         int splitPrice) {
        int fullBoxes = 0; // 出库数量，盒
        int leftoverPieces = 0;//出库数量 片
        int totalPrice;    // 总价格，单位分
        if (YesOrNoEnum.NO.getValue().equals(isSplit)) {
            //如果不允许拆分，那么totalOutQty代表的就是几盒，用几盒乘以一盒的价格
            totalPrice = totalOutQty * price;
        } else {
            // 允许拆零销售，拆分计算价格
            fullBoxes = totalOutQty / minPackQty;  // 整盒数量
            leftoverPieces = totalOutQty % minPackQty; // 零散片数
            //盒的价格+片的价格
            totalPrice = fullBoxes * price + leftoverPieces * splitPrice;
        }
        return totalPrice;
    }


    // 测试方法示例
    public static void main(String[] args) {
        Integer minPackQty = 12;           // 每盒12片
        Integer days = 1;                  // 用药周期15天
        Integer timesPerDay = 3;           // 每天3次
        BigDecimal dosePerTime = new BigDecimal(1); // 每次0.33片
        String isSplit = YesOrNoEnum.YES.getValue();            // 是否允许拆零销售，true表示允许拆零销售
        String isMinSplit = YesOrNoEnum.NO.getValue();        // 是否允许最小单位拆分，false表示每次用量向上取整整片

        int pricePerBox = 1000;            // 每盒价格3000分（30元）
        int pricePerPiece = 200;           // 单片价格250分（2.5元）

        // 计算总用量，考虑是否允许最小单位拆分
        int totalDose = calculateTotalDose(dosePerTime, timesPerDay, days, isMinSplit,isSplit,minPackQty);
        System.out.println("出库量(片): " + totalDose);

        // 计算出库数量和价格，考虑是否允许拆零销售
        Integer price = calculatePrice(totalDose, minPackQty, isSplit, pricePerBox, pricePerPiece);
        System.out.println("总价格(分): " + price);
    }


}


